#pragma once


#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <functional>






namespace fuh{
    template <class T = void>
    using func_t = std::function<void(T&)>;
    std::string GetThreadName()
    {
        static int number = 1;
        return std::to_string(number++);
    }

    template<class T = void>
    class thread{
        pthread_t m_tid;
        std::string m_threadname;
        func_t<T> m_func;
        bool m_isRuning;
        T m_data;
        public:
        thread(func_t<T> func,T & data,const std::string & threadName = "");
        thread(func_t<T> func,T && data,const std::string & threadName = "");
        ~thread();
        static void *ThreadRoutine(void* args)//这里加上，static，去掉隐含的参数
        {
            thread* td = (thread*)args;
            td->m_func(td->m_data);
            return nullptr;
        }
        bool Isrunning();
        std::string TName()
        {
            return m_threadname;
        }
        int Start();
        int join();
    };
};

template <class T>
int fuh::thread<T>:: Start()
{
    int n = pthread_create(&m_tid,nullptr,ThreadRoutine,(void*)this);
    return m_isRuning= !n;
}

template <class T>
int fuh::thread<T>:: join()
{
    if(!Isrunning())
    {
        return 1;
    }
    int n = pthread_join(m_tid,nullptr);
    if(n ==0 )
    {
        m_isRuning = false;
        std::cout<<"join Success\n";
        return 1;
    }
    return false;
}

template <class T>
fuh::thread<T>::thread(func_t<T> func, T & data,const std::string & threadName)
    :m_tid(0)
    ,m_func(func)
    ,m_isRuning(false)
    ,m_threadname("Thread")
    ,m_data(data)
    {
        m_threadname +=GetThreadName() + threadName;
    }
template <class T>
fuh::thread<T>::thread(func_t<T> func, T && data,const std::string & threadName)
    :m_tid(0)
    ,m_func(func)
    ,m_isRuning(false)
    ,m_threadname("Thread")
    ,m_data(data)
    {
        m_threadname +=GetThreadName() + threadName;
    }




template <class T>
fuh::thread<T>::~thread()
{
    join();
}
template <class T>
bool fuh::thread< T>:: Isrunning()
{
    return m_isRuning;
}